﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;

namespace AgilentDemo
{
    /// <summary>
    /// 安捷伦33500B信号源控制类
    /// </summary>
    public class AglientSignalSourceCtrol
    {
        /// <summary>
        /// 信号源通信连接
        /// </summary>
        private Socket _newclient;
        public Socket Newclient
        {
            get { return _newclient; }
        }

        public AglientSignalSourceCtrol()
        {
        }

        /// <summary>
        /// 初始化设备连接
        /// </summary>
        /// <param name="ipString">设备IP地址</param>
        /// <param name="port">设备端口号</param>
        /// <returns>是否连接成功</returns>
        public bool ConnectDevice(string ipString = "192.168.2.10", int port = 5025)
        {
            _newclient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            IPEndPoint ie = new IPEndPoint(IPAddress.Parse(ipString), port);
            try
            {
                _newclient.Connect(ie);
                return true;
            }
            catch (SocketException ex)
            {
                return false;
            }
        }

        /// <summary>
        /// 断开设备连接
        /// </summary>
        /// <returns>是否断开成功</returns>
        public bool DisConnectDevice()
        {
            try
            {
                _newclient.Disconnect(true);
                return true;
            }
            catch (SocketException ex)
            {
                return false;
            }
        }

        /// <summary>
        /// 外部触发正弦波
        /// </summary>
        /// <param name="freq">频率（单位Hz）</param>
        /// <param name="volt">电压（单位Vpp）</param>
        /// <param name="ncyc">循环次数</param>
        /// <param name="delay">延时（单位μs）</param>
        public void TriggerSinWave(int freq, float volt, int ncyc = 5, int delay = 50)
        {
            string str = "FUNCtion SIN\r\n";
            str += setFrequency(freq);
            str += setVoltage(volt);
            str += setBurst(ncyc, delay);
            str += "OUTP 1\r\n";

            send(str);
        }

        /// <summary>
        /// 外部触发任意波形
        /// </summary>
        /// <param name="arbName">波形名（带后缀）</param>
        /// <param name="rate">采样率（单位Sa/s）</param>
        /// <param name="volt">电压（单位Vpp）</param>
        /// <param name="ncyc">循环次数</param>
        /// <param name="delay">延时（单位μs）</param>
        public void TriggerArbWave(string arbName, int rate, float volt, int ncyc = 5, int delay = 50)
        {
            string str = clearArbMemory();
            str += loadArbData(arbName);
            str += "FUNC ARB\r\n";

            string path = string.Format(@"INT:\{0}\", "MYARBS");
            string wave = string.Format("{0}{1}", path, arbName);
            str += string.Format("FUNC:ARB \"{0}\"\r\n", wave);

            str += setBurst(ncyc, delay);

            str += setVoltage(volt);
            str += setSampleRate(rate);
            str += "OUTP 1\r\n";

            send(str);
        }

        /// <summary>
        /// 设置频率
        /// </summary>
        /// <param name="freq">频率（单位Hz）</param>
        public void SetFrequency(int freq)
        {
            string str = setFrequency(freq);
            str += "OUTP 1\r\n";

            send(str);
        }

        /// <summary>
        /// 设置采样率
        /// </summary>
        /// <param name="rate">采样率（单位Sa/s）</param>
        public void SetSampleRate(int rate)
        {
            string str = setSampleRate(rate);
            str += "OUTP 1\r\n";

            send(str);
        }

        /// <summary>
        /// 设置电压
        /// </summary>
        /// <param name="volt">电压（单位Vpp）</param>
        public void SetVoltage(float volt)
        {
            string str = setVoltage(volt);
            str += "OUTP 1\r\n";

            send(str);
        }

        /// <summary>
        /// 设置偏移
        /// </summary>
        /// <param name="offset">偏移（单位Vpp）</param>
        public void SetOffset(float offset)
        {
            string str = setOffset(offset);
            str += "OUTP 1\r\n";

            send(str);
        }

        /// <summary>
        /// 设置延时
        /// </summary>
        /// <param name="delay">延时（单位μs）</param>
        public void SetDelay(int delay)
        {
            string str = setBurst(1, delay);
            str += "OUTP 1\r\n";

            send(str);
        }

        /// <summary>
        /// 清空任意波形内存
        /// </summary>
        /// <returns></returns>
        private string clearArbMemory()
        {
            return "DATA:VOL:CLEAR\r\n";
        }

        /// <summary>
        /// 加载指定任意波形到内存
        /// </summary>
        /// <param name="folder">所在文件夹</param>
        /// <param name="arbName">波形名称</param>
        /// <returns></returns>
        private string loadArbData(string arbName, string folder = "MYARBS")
        {
            string path = string.Format(@"INT:\{0}\", folder);
            string wave = string.Format("{0}{1}", path, arbName);
            return string.Format("MMEM:LOAD:DATA \"{0}\"\r\n", wave);
        }

        /// <summary>
        /// 设置电压（单位Vpp）
        /// </summary>
        /// <param name="volt">电压值</param>
        /// <returns></returns>
        private string setVoltage(float volt)
        {
            return string.Format("VOLT +{0}\r\n", volt);
        }

        /// <summary>
        /// 设置偏移（单位Vpp）
        /// </summary>
        /// <param name="offset"></param>
        /// <returns></returns>
        private string setOffset(float offset)
        {
            return string.Format("VOLTage:OFFSet {0}\r\n", offset);
        }

        /// <summary>
        /// 设置采样率（单位Sa/s）
        /// </summary>
        /// <param name="rate">采样率</param>
        /// <returns></returns>
        private string setSampleRate(int rate)
        {
            return string.Format("FUNC:ARB:SRAT {0}\r\n", rate);
        }

        /// <summary>
        /// 设置频率（单位Hz）
        /// </summary>
        /// <param name="freq">频率</param>
        /// <returns></returns>
        private string setFrequency(int freq)
        {
            return string.Format("FREQuency {0}\r\n", freq);
        }

        /// <summary>
        /// 设置外触发
        /// </summary>
        /// <param name="ncyc">循环次数</param>
        /// <param name="delay">延时（微秒）</param>
        /// <returns></returns>
        private string setBurst(int ncyc = 1, int delay = 50)
        {
            string str = "BURS:MODE TRIG\r\n";
            str += string.Format("BURS:NCYC {0}\r\n", ncyc);
            str += "BURS:PHAS 0\r\n";
            str += "TRIG:SOUR EXT\r\n";
            str += string.Format("TRIG:DEL {0}e-6\r\n", delay);
            str += "BURS:STAT ON\r\n";
            return str;
        }

        /// <summary>
        /// 发送指令
        /// </summary>
        /// <param name="str">指令字符串</param>
        private void send(string str)
        {
            byte[] data = new byte[str.Length];
            data = Encoding.UTF8.GetBytes(str);
            _newclient.Send(data);
        }
    }
}
